package com.ea.admin.controller;

import com.ea.admin.pojo.param.account.ChangePasswordParam;
import com.ea.admin.pojo.param.auth.CheckPasswordParam;
import com.ea.admin.pojo.param.auth.LoginParam;
import com.ea.admin.pojo.vo.account.AdminInfoVo;
import com.ea.admin.pojo.vo.auth.AuthVo;
import com.ea.admin.service.AuthService;
import com.ea.admin.utils.NowUserGetter;
import com.ea.common.auth.NowUser;
import com.ea.common.log.LogAnnotation;
import com.ea.common.result.BizException;
import com.ea.common.result.ErrorCode;
import com.ea.common.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;

@RestController
@Api(tags = "登录账号的操作")
@RequestMapping("/auth")
public class AuthController {
    final AuthService authService;
    final NowUserGetter nowUserGetter;

    public AuthController(AuthService authService, NowUserGetter nowUserGetter) {
        this.authService = authService;
        this.nowUserGetter = nowUserGetter;
    }

    /**
     * 以username在redis中查询得出NowUser信息，redis中查询不到，则在数据库查询
     */
    @ApiIgnore
    @GetMapping("/getCurrentUser")
    public Result<NowUser> getNowUserByUsername(@RequestParam String username) {
        NowUser nowUserByUsername = authService.getNowUserByUsername(username);
        return Result.success(nowUserByUsername);
    }

    @ApiOperation(value = "管理员登录")
    @ApiImplicitParam(dataType = "LoginParam", name = "loginParam", value = "管理员登录需要的参数", readOnly = true, required = true)
    @PostMapping("/login")
    @LogAnnotation(module = "LoginLogoutController", operation = "管理员登录")
    public Result<AuthVo> login(@RequestBody @Valid LoginParam loginParam) {
        AuthVo result = authService.login(
                loginParam.getUsername(),
                loginParam.getPassword()
        );
        return Result.success(result);
    }

    @Transactional
    @Operation(summary = "获得当前管理员的信息")
    @PostMapping("/getAdminInfo")
    @LogAnnotation(module = "AccountController", operation = "获得当前管理员的信息")
    public Result<AdminInfoVo> getAdminInfo() {
        // 1. 检查用户是否已登录
        NowUser nowUser = nowUserGetter.getNowUser();
        if (nowUser == null) {
            // 用户未登录
            throw new BizException(ErrorCode.USER_LOGIN_ERROR_NO_LOGIN);
        }
        AdminInfoVo result = authService.getAdminInfo(
                nowUser.getAccountId()
        );
        return Result.success(result);
    }


    @ApiOperation(value = "校验密码是否正确")
    @ApiImplicitParam(dataType = "CheckPasswordParam", name = "checkPasswordParam", value = "校验密码", readOnly = true, required = true)
    @PostMapping("/checkPassword")
    @LogAnnotation(module = "LoginLogoutController", operation = "校验密码")
    public Result<Boolean> checkPassword(@RequestBody @Valid CheckPasswordParam checkPasswordParam) {
        // 1. 检查用户是否已登录
        NowUser nowUser = nowUserGetter.getNowUser();
        if (nowUser == null) {
            // 用户未登录
            throw new BizException(ErrorCode.USER_LOGIN_ERROR_NO_LOGIN);
        }

        Boolean result = authService.checkPassword(
                nowUserGetter.getUsername(),
                checkPasswordParam.getPassword()
        );
        return Result.success(result);
    }

    @ApiOperation(value = "管理员登出")
    @PostMapping("/logout")
    @LogAnnotation(module = "LoginLogoutController", operation = "管理员登出")
    public Result logout() {
        // 1. 检查用户是否已登录
        NowUser nowUser = nowUserGetter.getNowUser();
        if (nowUser == null) {
            // 用户未登录
            throw new BizException(ErrorCode.USER_LOGIN_ERROR_NO_LOGIN);
        }

        authService.logout(
                nowUserGetter.getNowUser().getAccountId(),
                nowUserGetter.getToken()
        );
        return Result.success(null);
    }

    @Transactional
    @ApiOperation(value = "修改密码")
    @ApiImplicitParam(dataType = "ChangePasswordParam", name = "changePasswordParam", value = "修改密码所需的参数", readOnly = true, required = true)
    @PostMapping("/changePassword")
    @LogAnnotation(module = "AccountController", operation = "修改密码")
    public Result changePassword(@RequestBody @Valid ChangePasswordParam changePasswordParam) {
        // 1. 检查用户是否已登录
        NowUser nowUser = nowUserGetter.getNowUser();
        if (nowUser == null) {
            // 用户未登录
            throw new BizException(ErrorCode.USER_LOGIN_ERROR_NO_LOGIN);
        }
        // 2. 检查传入的password和rePassword是否相同，不相同的话，则报“密码和确认密码不一致”错误
        if (!changePasswordParam.getPassword().equals(changePasswordParam.getRePassword())) {
            throw new BizException(ErrorCode.USER_REGISTER_ERROR_PASSWORD_NOT_EQUALS);
        }

        authService.changePassword(
                nowUser.getAccountId(),
                changePasswordParam.getOldPassword(),
                changePasswordParam.getPassword(),
                nowUserGetter.getToken()
        );
        return Result.success(null);
    }

}
